﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct Goods
{
	string _name; // 名字
	double _price; // 价格
	int _evaluate; // 评价
	//...

	Goods(const char* str, double price, int evaluate)
		:_name(str)
		, _price(price)
		, _evaluate(evaluate)
	{}
};

//升序
struct Compare1
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price < gr._price;
	}
};
//降序
struct Compare2
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price > gr._price;
	}
};

//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };
//
//	sort(v.begin(), v.end(), Compare1());//按照升序排
//	sort(v.begin(), v.end(), Compare2());//按照降序排
//
//	//价格升序
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)->bool
//		{
//			return g1._price < g2._price;
//		});
//	//价格降序
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)->bool
//		{
//			return g1._price > g2._price;
//		});
//
//	return 0;
//}

// lambda表达式本质是⼀个匿名函数的对象，跟普通函数不同的是他可以定义在函数内部
//lambda表达式的格式：[capture-list] (parameters)->return type {function boby }
//                      捕捉列表          参数       返回值类型       函数体
//int main()
//{
//	auto add1 = [](int x, int y)->int {return x + y; };//这是一个函数;lambda表达式看作是一个匿名函数对象传给add1
//	cout << add1(1, 2) << endl;
//
//	auto func1 = []( )->int //  有多行的情况下
//		{
//			cout << "hello world" << endl;
//			return 0;
//		};
//
//	auto func2 = [] //无参可以省略参数;
//		{
//			cout << "hello world" << endl;
//		};
//
//	func1();//调用func1
//	func2();//调用func2
//	return 0;
//}


//int main()
//{
//	int a = 0, b = 1;
//
//	auto swap1 = [](int& x, int& y)
//	{
//			// 只能用当前lambda局部域和捕捉的对象
//			int tmp = x;
//			x = y;
//			y = tmp;
//	};
//	swap1(a, b);
//
//	// 传值捕捉本质是一种拷贝,并且const修饰了
//	// mutable相当于去掉const属性，可以修改了
//	// 但是修改了不会影响外面被捕捉的值，因为是一种拷贝
//	auto swap2 = [a, b]()mutable
//	{
//			int tmp = a;
//			a = b;
//			b = tmp;
//	};
//	swap2();
//
//	//所以要使用引用捕捉
//	//此处的&a,&b是引用不是取地址
//	auto swap3 = [&a, &b]()
//	{
//			int tmp = a;
//			a = b;
//			b = tmp;
//	};
//	swap3();
//
//	return 0;
//}


//int main()
//{
//	int a = 0, b = 1, c = 2, d = 3;
//
//	//传值捕捉
//	auto func2 = [=]
//	{
//			int ret = a + b + c + d;
//			return ret;
//	};
//	cout << func2() << endl;
//
//	//所有值传引用捕捉
//	auto func3 = [&]
//	{
//			a++;
//			c++;
//			d++;
//			int ret = a + b + c + d;
//			return ret;
//	};
//
//	//混合捕捉
//	auto func3 = [&a,b]
//		{
//			a++;
//			//b++;不可以修改;因为是传值的
//			int ret = a + b ;
//			return ret;
//		};
//
//	//所有值以引用方式捕捉,d用传值捕捉
//	auto func4 = [&, d]
//		{
//			a++;
//			//b++;不可以修改;因为是传值的
//			int ret = a + b+c+d;
//			return ret;
//		};
//
//	//所有值以传值捕捉,d以引用捕捉
//	auto func4 = [=, &d]
//		{
//			//a++;
//			//b++;不可以修改;因为是传值的
//			int ret = a + b + c + d;
//			return ret;
//		};
//}

//包装器
//function用法:
#include<functional>
//int f(int a, int b)
//{
//	return a + b;
//}
//
//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return a + b;
//	}
//};
//
//class Plus
//{
//public:
//	static int plusi(int a, int b)//静态成员变量
//	{
//		return a + b;
//	}
//
//	double plusd(double a, double b)
//	{
//		return a + b;
//	}
//};
//int main() 
//{
//	// 包装可调用对象
//	function<int(int, int)> f1 = f;//函数指针
//	function<int(int, int)> f2 = Functor();//方函数
//	function<int(int, int)> f3 = [](int a, int b) {return a + b; };//lamda
//	cout << f1(1, 1) << endl;
//	cout << f2(1, 1) << endl;
//	cout << f3(1, 1) << endl;
//
//	// 包装静态成员函数
//	function<int(int, int)> f4 = Plus::plusi;
//	cout << f4(1, 1) << endl;
//
//	// 包装非静态成员函数要加&;error
//	function<double(double, double)> f5 = &Plus::plusi;
//	cout << f5(1.1, 1.1) << endl;
//
//	// 包装非静态成员函数
//   // 普通成员函数还有⼀个隐含的this指针参数，所以绑定时传对象或者对象的指针过去都可以
//	function<double(Plus*, double, double)> f21 = &Plus::plusd;
//	Plus pd;
//	cout << f21(&pd, 1.1, 1.1) << endl;
//
//	//传对象
//	function<double(Plus, double, double)> f6 = &Plus::plusd;//function不是直接传给plusd
//	cout << f6(pd, 1.1, 1.1) << endl;
//	cout << f6(Plus(), 1.1, 1.1) << endl;
//	return 0;
//}


//bind包装器
using placeholders::_1;
using placeholders::_2;
using placeholders::_3;

int Sub(int a, int b)
{
	return (a - b) * 10;
}
int main()
{
	//调整参数顺序    sub1是可调用对象
	auto sub1 = bind(Sub, _1, _2);//_1代表first参数;_2代表第二个实参数.....
	cout << sub1(10, 5) << endl;

	auto sub2 = bind(Sub, _2, _1);//_1代表first参数;_2代表第二个参数.....
	cout << sub2(10, 5) << endl;


	//调整参数个数
	auto sub3 = bind(Sub, 100, _1);//第一个参数固定死为100;_1相当于第二个参数;还是从_1开始
	cout << sub3(5);//只需要传第二个参数;5==_1

	auto sub4 = bind(Sub, _1, 1);//第二个参数固定死为1;_1相当于第一个参数

	// bind本质返回一个仿函数对象
	// bind一般用于，绑死一些固定参数
	function<double(double, double)> f7 = bind(&Plus::plusd, Plus(), _1, _2);
	cout << f7(1.1, 1.1) << endl;

	//auto func1 = [](double rate, double monty, int year)->double {return monty * rate * year;};
	auto func1 = [](double rate, double monty, int year)->double {
		double ret = monty;
		for (int i = 0; i < year; i++)
		{
			ret += ret * rate;
		}

		return ret - monty;
		};

	function<double(double)> func3_1_5 = bind(func1, 0.015, _1, 3);
	function<double(double)> func5_1_5 = bind(func1, 0.015, _1, 5);
	function<double(double)> func10_2_5 = bind(func1, 0.025, _1, 10);
	function<double(double)> func20_3_5 = bind(func1, 0.035, _1, 30);

	return 0;
}